package com.qf.boot2202day03.controller;

import cn.hutool.captcha.LineCaptcha;
import cn.hutool.crypto.digest.DigestUtil;

import com.qf.boot2202day03.entity.User;
import com.qf.boot2202day03.service.UserSevice;
import com.qf.boot2202day03.utils.Constants;
import com.qf.boot2202day03.vo.ResultVo;
import com.qf.boot2202day03.vo.TableVo;
import com.qf.boot2202day03.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/user")
@Slf4j   // 添加该注解后，可以使用 log对象进行日志的打印
public class UserController {

    @Autowired
    private UserSevice userSevice;

    @Value("${pic.dir}")
    private String picDir;

    @PostMapping("/login")
    public ResultVo login(String username, String password, String capchar, String autologin,
                          HttpServletResponse response, HttpSession session){

        log.info("username={},password={},capchar={}",username,password,capchar);

        //1. 处理验证码是否正确
        final LineCaptcha sessionCapchar = (LineCaptcha) session.getAttribute(Constants.HUTOOL_CAPCHAR);

        if (!sessionCapchar.verify(capchar)) {
            return new ResultVo(Constants.FAIL_CODE,"验证码错误");
        }

        //2. 调用service层的方法进行登录验证
        User user =  userSevice.login(username,password);
        log.info("调用service层方法校验用户密码，返回的user对象={}",user);

        //3. 如果user不为null，则代表登录成功，如果user为null，则登录失败
        if (user != null){

            // 如果用户登录成功，把user对象存入session
            session.setAttribute(Constants.SESSION_USER_KEY,user);

            if ("on".equals(autologin)){
                // 生成用于免登录的cookie ，cookie中的信息包含用户名和密码
                final String md5password = DigestUtil.md5Hex(password);
                String cookievalue =  username+"-"+md5password;
                final Cookie cookie = new Cookie(Constants.USER_TOKEN, cookievalue);
                cookie.setPath("/");  // 设置cookie为该域的顶级cookie
                cookie.setMaxAge(60*60*24*14);  // 两周有效期
                log.debug("用户设置免登录,cookie={}",cookievalue);
                response.addCookie(cookie);
            }


           return new ResultVo(Constants.SUCCESS_CODE,"登录成功");

        }else {
            return new ResultVo(Constants.FAIL_CODE,"登录失败");
        }


    }

    /**
     * 用户注册接口，该接口接收的是文件上传请求
     * @param userVo
     * @param session
     * @return
     */
    @PostMapping("/regist")
    public ResultVo regist(UserVo userVo, HttpSession session) throws IOException {

        log.info("用户注册请求处理, userVo={}",userVo);

        //1. 处理验证码是否正确
        final LineCaptcha sessionCapchar = (LineCaptcha) session.getAttribute(Constants.HUTOOL_CAPCHAR);

        if (sessionCapchar!=null && !sessionCapchar.verify(userVo.getCapchar())){
            return new ResultVo(Constants.FAIL_CODE,"验证码错误");
        }


        //2. 调用service层方法完成注册的业务逻辑
//        final String realPath = session.getServletContext().getRealPath(Constants.UPLOAD_PATH);

        ResultVo resultVo = userSevice.regist(userVo,this.picDir);

        return resultVo;
    }

    /**
     * 获取登录用户的用户名
     * @param session
     * @return
     */
    @GetMapping("/currentuser")
    public ResultVo getCurrentUser(HttpSession session){

        //从session中获取当前登录用户 的用户名
        final User user = (User) session.getAttribute(Constants.SESSION_USER_KEY);
        log.debug("获取当前登录用户，user={}",user);
        if (user!=null){

            return new ResultVo(Constants.SUCCESS_CODE, "获取登录用户成功", user.getName());
        }else {
            return new ResultVo(Constants.FAIL_CODE, "获取登录用户失败");
        }

    }

    /**
     * 获取当前登录用户的头像
     */
    @GetMapping("/pic")
    public void getPic(HttpSession session, HttpServletResponse response) throws IOException {
        //从session中获取当前登录用户 的用户名
        final User user = (User) session.getAttribute(Constants.SESSION_USER_KEY);
        if (user!=null){

            final String photopath = user.getPhotopath();


            final String finalFilepath = this.picDir + File.separator + photopath;
            log.debug("获取登录用户的头像，文件路径为={}",finalFilepath);
            // 把图片文件响应给浏览器
            IOUtils.copy(new FileInputStream(finalFilepath),response.getOutputStream());

        }else {

            return;

        }
    }


    @GetMapping("/checkusername")
    public ResultVo checkusername(String username){
        // 调用service层检查用户名是否存在
        ResultVo resultVo = userSevice.checkUsername(username);
        log.debug("检查用户名是否存在，username={},resultVo={}",username,resultVo);
        return resultVo;

    }

    /**
     * 用户数据表格分页查询接口
     * @param page  页号
     * @param limit 页大小
     * @return
     */
    @GetMapping("/getAllUsers")
    public TableVo<User> getAllUser(Integer page,Integer limit){

        log.debug("分页查询用户，page={},limit={}",page,limit);

        TableVo tableVo = userSevice.getAllUserByPage(page,limit);

        log.debug("查询到的结果为，tableVo={}",tableVo);

        return tableVo;
    }


    /**
     * 使用分页插件实现
     * @param page
     * @param limit
     * @return
     */
    @GetMapping("/getUserByPagehelper")
    public TableVo<User> getUserByPagehelper(Integer page,Integer limit){

        log.debug("分页查询用户，page={},limit={}",page,limit);

        TableVo tableVo = userSevice.getUserByPagehelper(page,limit);

        log.debug("查询到的结果为，tableVo={}",tableVo);

        return tableVo;
    }


    /**
     * 添加用户接口
     * @param user
     * @return
     */
    @PostMapping("/add")
    public ResultVo add(User user){

        log.debug("接收到参数，user={}",user);

        ResultVo resultVo = userSevice.addUser(user);
        log.debug("新增结果为,resultVo={}",resultVo);
        return resultVo;
    }


    /**
     * @RequestParam 这个注解可以处理方法参数名和请求参数名不一致的情况
     * @param idarray
     * @return
     */
    @RequestMapping("/del")
    public ResultVo del(@RequestParam("ids") List<Integer> idarray){

        log.debug("收到参数:ids={}",idarray);

        ResultVo resultVo = userSevice.deleteUserByIds(idarray);

        log.debug("删除结果为,resultVo={}",resultVo);
        return resultVo;
    }


    @PostMapping("/update")
    public ResultVo update(User user){

        log.debug("收到参数,user={}",user);
        ResultVo resultVo = userSevice.updateUser(user);
        log.debug("修改结果为,resultVo={}",resultVo);
        return resultVo;
    }


    /**
     * 带查询条件的数据表格接口
     * @param page
     * @param limit
     * @param userVo
     * @return
     */
    @GetMapping("/getUsersByContdition")
    public TableVo<User> getUsersByContdition(Integer page,Integer limit,UserVo userVo){

        log.debug("收到参数,page={},limit={},userVo={}",page,limit,userVo);

        TableVo<User> result =  userSevice.getUsersByContdition(page,limit,userVo);

        return result;
    }

    @GetMapping("/export")
    public ResultVo export() throws IOException {

        //1. 调用service层的方法进行数据导出，生成文件
        String filename = userSevice.export();

        //2. 返回包含文件名的 resultVO
        return new ResultVo(Constants.SUCCESS_CODE,"导出文件成功",filename);

    }

}
